package net.lab1024.sa.admin.module.business.category.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.common.DateTimeUtils;
import net.lab1024.sa.admin.common.EnumConverter;
import net.lab1024.sa.admin.config.UserContextHolder;
import net.lab1024.sa.admin.module.business.category.dao.OperationLogMapper;
import net.lab1024.sa.admin.module.business.category.dao.UserDao;
import net.lab1024.sa.admin.module.business.category.domain.dto.OperationLogDTO;
import net.lab1024.sa.admin.module.business.category.domain.entity.*;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

// 假设的自定义类

@Service
@Slf4j
@RequiredArgsConstructor
public class OperationLogService {
    private final OperationLogMapper logMapper;

    @Autowired
    UserDao userDao;

    /**
     * 异步保存日志
     */
    @Async("logTaskExecutor")
    public void saveLogAsync(OperationLog operationLog) {
        try {
            logMapper.insert(operationLog);
        } catch (Exception e) {
            log.error("保存操作日志失败", e);
        }
    }

    /**
     * 分页查询操作日志
     */
    public Page<OperationLogDTO> listLogs(LogQuery query) {
        Page<OperationLog> page = Page.of(query.getPage(), query.getSize());
        LambdaQueryWrapper<OperationLog> wrapper = buildQueryWrapper(query);
        Page<OperationLog> operationLogPage = logMapper.selectPage(page, wrapper);
        // 获取查询结果列表
        List<OperationLog> operationLogList = operationLogPage.getRecords();
        // 转换 OperationLog 列表为 OperationLogDTO 列表
        List<OperationLogDTO> operationLogDTOList = operationLogList.stream()
                .map(operationLog -> {
                    OperationLogDTO operationLogDTO = new OperationLogDTO();
                    // 使用 BeanUtils 复制属性
                    BeanUtils.copyProperties(operationLog, operationLogDTO);
                    // 转换枚举值为显示名称
                    String result = DateTimeUtils.getStrDateTime(operationLog.getCreateTime());
                    operationLogDTO.setStrCreateTime(result);
                    // 如果有其他需要手动设置的属性，可以在这里处理
                    return operationLogDTO;
                })
                .collect(Collectors.toList());

        // 创建新的 Page 对象来包装转换后的 DTO 列表
        Page<OperationLogDTO> resultPage = new Page<>();
        resultPage.setRecords(operationLogDTOList);
        resultPage.setTotal(operationLogPage.getTotal());
        resultPage.setCurrent(operationLogPage.getCurrent());
        resultPage.setSize(operationLogPage.getSize());

        return resultPage;
    }

    /**
     * 查询所有符合条件的操作日志（用于导出）
     */
    public List<OperationLog> listAllLogs(LogQuery query) {
        LambdaQueryWrapper<OperationLog> wrapper = buildQueryWrapper(query);
        return logMapper.selectList(wrapper);
    }

    /**
     * 构建查询条件
     */
    private LambdaQueryWrapper<OperationLog> buildQueryWrapper(LogQuery query) {
        LambdaQueryWrapper<OperationLog> wrapper = new LambdaQueryWrapper<>();

        wrapper.like(StringUtils.isNotBlank(query.getOperatorPhone()),
                OperationLog::getOperatorPhone, query.getOperatorPhone())
                .eq(StringUtils.isNotBlank(query.getModule()),
                        OperationLog::getModule, query.getModule())
                .eq(StringUtils.isNotBlank(query.getResult()),
                        OperationLog::getResult, query.getResult())
                .eq(StringUtils.isNotBlank(query.getClassName()),
                        OperationLog::getClassName, query.getClassName())
                .ge(query.getStartTime() != null,
                        OperationLog::getCreateTime, query.getStartTime())
                .le(query.getEndTime() != null,
                        OperationLog::getCreateTime, query.getEndTime())
                .orderByDesc(OperationLog::getCreateTime);

        UserContext userContext = UserContextHolder.getUserContext();
        String userId = userContext.getUserId();
        User user = userDao.selectById(Long.valueOf(userId));

        if (EnumConverter.generalUserRoleCode.equals(user.getRole())) {
            wrapper.eq(true,
                    OperationLog::getOperatorName, userContext.getUsername())
                    .eq(true,
                            OperationLog::getOperatorCode, userContext.getUserCode());
        } else {
            wrapper.like(StringUtils.isNotBlank(query.getOperatorName()),
                    OperationLog::getOperatorName, query.getOperatorName());
            wrapper.like(StringUtils.isNotBlank(query.getOperatorCode()),
                    OperationLog::getOperatorCode, query.getOperatorCode());
        }

        return wrapper;
    }


}